package com.foreverwin.jzymes.websocket;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.foreverwin.jzymes.common.mapper.DashBoardAdviceMapper;
import com.foreverwin.jzymes.common.service.IActivityRuleAdviceService;
import com.foreverwin.jzymes.common.service.IProductionShiftService;
import com.foreverwin.jzymes.framework.annotation.WebSocketHandler;
import com.foreverwin.jzymes.framework.event.AppEvent;
import com.foreverwin.jzymes.framework.websocket.TextMessageWebSocketWraper;
import org.springframework.beans.factory.annotation.Autowired;

import java.math.BigDecimal;
import java.util.*;

@WebSocketHandler( channel = "Z_DB_TOP_5_NC" )
public class TopFiveNCHandler extends TextMessageWebSocketWraper {

    @Autowired
    private IActivityRuleAdviceService activityRuleAdviceService;
    @Autowired
    private IProductionShiftService productionShiftService;
    @Autowired
    private DashBoardAdviceMapper dashBoardAdviceMapper;

    private Map<String,String> activityRuleMap;

    @Override
    public void doAfterOpen(Connection connection) {
        activityRuleMap = activityRuleAdviceService.findActivityRules( getChannel() );
    }

    @Override
    public void doAfterClose() {

    }

    @Override
    public JSONObject doReceiveAndReply(String messageType, JSONObject requestParams) {
        String site = activityRuleMap.get( "SITE" );
        String inspect = activityRuleMap.get( "INSPECT" );
        String debur = activityRuleMap.get( "DEBUR" );
        String fqc = activityRuleMap.get( "FQC" );
        String operation = requestParams.getString( "OPERATION" );
        if( "WS_OPERATION_NC".equals( messageType ) ){
            JSONObject response = new JSONObject();
            response.put( inspect, buildInspectNcCodeList( site, inspect ) );
            response.put( debur, buildDeburNcCodeList( site, debur ) );
            response.put( fqc, buildFqcNcCodeList( site ) );
            sendMessage( response );
        }else if( "WS_NC_CNC".equals( messageType ) ){
            String ncCode = requestParams.getString( "NC_CODE" );
            if( operation.equals( inspect ) ){
                buildInspectCncNcData( site, operation, ncCode );
            }
            if( operation.equals( debur ) ){
                buildDeburCncNcData( site, operation, ncCode );
            }
            if( operation.equals( fqc ) ){
                buildFqcCncNcData( site, ncCode );
            }
        }

        return null;
    }

    @Override
    public void onAppEvent(AppEvent<?> appEvent) {

    }

    /**
     * 全检Top5不良代码
     *
     * @param site
     * @param operation
     */
    public JSONArray buildInspectNcCodeList( String site, String operation ){

        Date[] dateRange = productionShiftService.findShiftRange( site, new Date() );
        List<Map<String,Object>> ncCodeList = dashBoardAdviceMapper.findNcDataSummaryByOperation( site, operation, dateRange[0] );
        sortList( ncCodeList );
        JSONArray ncCodes = new JSONArray();
        for( Map<String,Object> ncCode : ncCodeList ){
            if( ncCodes.size() < 5 ){
                JSONObject nc = new JSONObject();
                nc.put( "id", ncCode.get( "NC_CODE" ) );
                nc.put( "qty", ncCode.get( "QTY" ) );
                ncCodes.add( nc );
            }else {
                break;
            }
        }
        return ncCodes;
    }

    /**
     * 去毛刺Top5不良代码
     *
     * @param site
     * @param operation
     */
    public JSONArray buildDeburNcCodeList( String site, String operation ){

        Date[] dateRange = productionShiftService.findShiftRange( site, new Date() );
        List<Map<String,Object>> deburNcList = dashBoardAdviceMapper.findNcDataSummaryByOperation( site, operation, dateRange[0] );

        /**排除去毛刺不良数量*/
        List<Map<String,Object>> fqcNcList = dashBoardAdviceMapper.findFqcNcSummaryByDate( site, dateRange[0] );
        for( Map<String,Object> fqcNc : fqcNcList ){
            Map<String,Object> nc = null;
            for( Map<String,Object> deburNc : deburNcList ){
                if( fqcNc.get( "NC_CODE" ).equals( deburNc.get("NC_CODE") ) ){
                    BigDecimal fqcNcQty = (BigDecimal) fqcNc.get( "QTY" );
                    BigDecimal deburNcQty = (BigDecimal) deburNc.get( "QTY" );
                    deburNc.put( "QTY", deburNcQty.subtract( fqcNcQty ) );
                    nc = deburNc;
                    break;
                }
            }
            if( nc != null && ( (BigDecimal)nc.get( "QTY" ) ).intValue() == 0 ){
                deburNcList.remove( nc );
            }
        }
        sortList( deburNcList );
        JSONArray ncCodes = new JSONArray();
        for( Map<String,Object> ncCode : deburNcList ){
            if( ncCodes.size() < 5 ){
                JSONObject nc = new JSONObject();
                nc.put( "id", ncCode.get( "NC_CODE" ) );
                nc.put( "qty", ncCode.get( "QTY" ) );
                ncCodes.add( nc );
            }else {
                break;
            }
        }
        return ncCodes;
    }

    /**
     * FQC Top5不良代码
     *
     * @param site
     */
    public JSONArray buildFqcNcCodeList( String site ){
        Date[] dateRange = productionShiftService.findShiftRange( site, new Date() );
        List<Map<String,Object>> fqcNcList = dashBoardAdviceMapper.findFqcNcSummaryByDate( site, dateRange[0] );
        sortList( fqcNcList );
        JSONArray ncCodes = new JSONArray();
        for( Map<String,Object> ncCode : fqcNcList ){
            if( ncCodes.size() < 5 ){
                JSONObject nc = new JSONObject();
                nc.put( "id", ncCode.get( "NC_CODE" ) );
                nc.put( "qty", ncCode.get( "QTY" ) );
                ncCodes.add( nc );
            }else {
                break;
            }
        }
        return ncCodes;
    }

    /**
     * 全检CNC不良分布
     *
     * @param site
     * @param operation
     * @param ncCode
     */
    public void buildInspectCncNcData( String site, String operation, String ncCode ){

        Date[] dateRange = productionShiftService.findShiftRange( site, new Date() );
        List<Map<String,Object>> cncNcList = dashBoardAdviceMapper.findNcDataSummaryByNcCode( site, operation, ncCode, dateRange[0] );
        JSONArray details = new JSONArray();
        for( Map<String,Object> cncNc : cncNcList ){
            JSONObject nc = new JSONObject();
            nc.put( "id", cncNc.get( "CNC" ) );
            nc.put( "qty", cncNc.get( "QTY" ) );
            details.add( nc );
        }
        JSONObject response = new JSONObject();
        response.put( "ncCode", ncCode );
        response.put( "details", details );
        sendMessage( response );
    }

    /**
     * 去毛刺CNC不良分布
     *
     * @param site
     * @param operation
     * @param ncCode
     */
    public void buildDeburCncNcData( String site, String operation, String ncCode ){
        Date[] dateRange = productionShiftService.findShiftRange( site, new Date() );
        List<Map<String,Object>> deburCncNcList = dashBoardAdviceMapper.findNcDataSummaryByNcCode( site, operation, ncCode, dateRange[0] );
        List<Map<String,Object>> fqcCncNcList = dashBoardAdviceMapper.findFqcNcSummaryByNcCode( site, ncCode, dateRange[0] );

        JSONArray details = new JSONArray();
        for( Map<String,Object> deburCncNc : deburCncNcList ){

            for( Map<String,Object> fqcCncNc : fqcCncNcList ){
                if( fqcCncNc.get( "CNC" ).equals( deburCncNc.get("CNC") ) ){
                    BigDecimal fqcNcQty = (BigDecimal) fqcCncNc.get( "QTY" );
                    BigDecimal deburNcQty = (BigDecimal) deburCncNc.get( "QTY" );
                    deburCncNc.put( "QTY", deburNcQty.subtract( fqcNcQty ) );
                }
            }

            JSONObject nc = new JSONObject();
            nc.put( "id", deburCncNc.get( "CNC" ) );
            nc.put( "qty", deburCncNc.get( "QTY" ) );
            details.add( nc );
        }

        JSONObject response = new JSONObject();
        response.put( "ncCode", ncCode );
        response.put( "details", details );
        sendMessage( response );
    }

    /**
     * FQC CNC不良分布
     *
     * @param site
     * @param ncCode
     */
    public void buildFqcCncNcData( String site, String ncCode ){
        Date[] dateRange = productionShiftService.findShiftRange( site, new Date() );
        List<Map<String,Object>> cncNcList = dashBoardAdviceMapper.findFqcNcSummaryByNcCode( site, ncCode, dateRange[0] );
        JSONArray details = new JSONArray();
        for( Map<String,Object> cncNc : cncNcList ){
            JSONObject nc = new JSONObject();
            nc.put( "id", cncNc.get( "CNC" ) );
            nc.put( "qty", cncNc.get( "QTY" ) );
            details.add( nc );
        }
        JSONObject response = new JSONObject();
        response.put( "ncCode", ncCode );
        response.put( "details", details );
        sendMessage( response );
    }

    public void sortList( List<Map<String,Object>> list ){
        Collections.sort( list, new Comparator<Map<String, Object>>() {
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                BigDecimal map1value = (BigDecimal) o1.get( "QTY" );
                BigDecimal map2value = (BigDecimal) o2.get( "QTY" );
                return map1value.compareTo( map2value ) * -1;
            }
        } );
    }
}
